using System.Windows.Input;
using System.Collections;
using Quizzer.Model;
using Quizzer.Helpers;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using System;
using System.Windows;

namespace Quizzer.ViewModel
{
    [Magic]
    public class MainViewModel : ViewModelBase
    {
        // If you want to add new ViewModel, than:
        // 1. Add field in MainViewModel
        // 2. Add statement for navigation in ReceiveMessage(string vm) method
        // 3. Add DataTemplate to App.xaml

        // There two types of navigation now:
        // 1. In constructor of MainViewModel - Messenger.Default.Register<string>(this, ReceiveMessage)
        //    In any VM if you want to navigate to some page you need to write: 
        //    Messenger.Default.Send<string, MainViewModel>("CoursesPage")   -- Write your string instead of "CoursesPage"
        //    In that case you need to add statements for each VM to ReceiveMessage(string vm) method.
        // 2. In constructor of MainViewModel - Messenger.Default.Register<ViewModelBase>(this, ReceiveMessage);
        //    In any VM if you want to navigate to some page you need to write: 
        //    Messenger.Default.Send<ViewModelBase, MainViewModel>(new CoursesViewModel()); -- Write your string instead of "new CoursesViewModel()"
        //    But in that case constructor of viewmodel that you navigate to calling two times

        #region Constructor and Receivers

        public MainViewModel()
        {
            ////if (IsInDesignMode)
            ////    { Code runs in Blend --> create design time data. }
            ////else
            ////    { Code runs "for real" }

            //CurrentViewModel = new LoginViewModel();
            
            // Create some data
            new Quizzer.Model.SampleData();
            
            // Set current ViewModel
            CurrentViewModel = _loginViewModel;
            
            // Do some actions to make Back button work properly
            NavigationStack.Push("LoginPage");
            IsBackVisible = Visibility.Visible;

            // Register commands
            CloseApplication = new RelayCommand(() => ExecuteCloseApplication());
            Back = new RelayCommand(() => ExecuteBack());

            // Register messages
            Messenger.Default.Register<string>(this, ReceiveMessage);

            // This message receiving only on QuestionPages
            Messenger.Default.Register<ViewModelBase>(this, ReceiveMessage);
        }

        // Call this method when message received
        private void ReceiveMessage(string vm)
        {
            if (vm != "QuestionPage")                   
            {
                NavigationStack.Push(vm);                       // On QuestionPage's navigation doesn't work
                IsBackVisible = Visibility.Visible;
            }
            else
                IsBackVisible = Visibility.Hidden;      // Hide back button, when user on QuestionPage

            switch (vm) // for navigation beetween pages specific string should be send.
            {
                case "LoginPage": CurrentViewModel = _loginViewModel; break;
                case "RegistrationPage": CurrentViewModel = _registrationViewModel; break;
                case "CoursesPage": CurrentViewModel = _coursesViewModel; break;
                case "ProfilePage": CurrentViewModel = _profileViewModel; break;
                case "QuestionPage": CurrentViewModel = _questionViewModel; break;
                case "TestInfoPage": CurrentViewModel = _testInfoViewModel; break;
                case "TestResultPage": CurrentViewModel = _testResultViewModel; break;
                case "CreateTestPage": CurrentViewModel = _createTestViewModel; break;
                default: break;
            }
        }

        // This method calling only on QuestionPages
        private void ReceiveMessage(ViewModelBase vm)
        {
            CurrentViewModel = vm;
        }

        #endregion

        #region Fields

        // Fields for navigation
        public Visibility IsBackVisible { get; set; }
        private Stack NavigationStack = new Stack();

        // Register all ViewModels
        readonly static LoginViewModel _loginViewModel = new LoginViewModel();
        readonly static RegistrationViewModel _registrationViewModel = new RegistrationViewModel();
        readonly static CoursesViewModel _coursesViewModel = new CoursesViewModel();
        readonly static ProfileViewModel _profileViewModel = new ProfileViewModel();
        readonly static TestInfoViewModel _testInfoViewModel = new TestInfoViewModel();
        readonly static QuestionViewModel _questionViewModel = new QuestionViewModel();
        readonly static TestResultViewModel _testResultViewModel = new TestResultViewModel();
        readonly static CreateTestViewModel _createTestViewModel = new CreateTestViewModel();

        #endregion

        #region Properties

        /// The CurrentView property. If the View is changed,
        /// we need to raise a property changed event.
        public ViewModelBase CurrentViewModel { get; private set; }
        
        #endregion

        #region Commands

        public ICommand CloseApplication { get; private set; }
        private void ExecuteCloseApplication()
        { App.Current.Shutdown(); }

        public ICommand Back { get; private set; }
        private void ExecuteBack()
        {
            if (CurrentViewModel.GetType() != typeof(QuestionViewModel))    // if CurrentVM != QuestionVM, then...
            {
                NavigationStack.Pop();                                      // Pop current VM from stack
                Messenger.Default.Send<string, MainViewModel>(NavigationStack.Pop().ToString());    // Pop previous VM from stack
            }
        }

        #endregion

    }
}